home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / BYacc-CW 1.9 / output.c < prev    next >
C/C++ Source or Header  |  1995-05-20  |  23KB  |  1,206 lines

  1. #include "defs.h"
  2.  
  3. #include <string.h>
  4.  
  5. static int nvectors;
  6. static int nentries;
  7. static short **froms;
  8. static short **tos;
  9. static short *tally;
  10. static short *width;
  11. static short *state_count;
  12. static short *order;
  13. static short *base;
  14. static short *pos;
  15. static int maxtable;
  16. static short *table;
  17. static short *check;
  18. static int lowzero;
  19. static int high;
  20.  
  21.  
  22.  
  23.  
  24. static void output_prefix(void)
  25. {
  26.     if (symbol_prefix == NULL)
  27.     symbol_prefix = "yy";
  28.     else
  29.     {
  30.     ++y_outline;
  31.     fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix);
  32.     ++y_outline;
  33.     fprintf(code_file, "#define yylex %slex\n", symbol_prefix);
  34.     ++y_outline;
  35.     fprintf(code_file, "#define yyerror %serror\n", symbol_prefix);
  36.     ++y_outline;
  37.     fprintf(code_file, "#define yychar %schar\n", symbol_prefix);
  38.     ++y_outline;
  39.     fprintf(code_file, "#define yyval %sval\n", symbol_prefix);
  40.     ++y_outline;
  41.     fprintf(code_file, "#define yylval %slval\n", symbol_prefix);
  42.     ++y_outline;
  43.     fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix);
  44.     ++y_outline;
  45.     fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix);
  46.     ++y_outline;
  47.     fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix);
  48.     ++y_outline;
  49.     fprintf(code_file, "#define yyss %sss\n", symbol_prefix);
  50.     ++y_outline;
  51.     fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix);
  52.     ++y_outline;
  53.     fprintf(code_file, "#define yyvs %svs\n", symbol_prefix);
  54.     ++y_outline;
  55.     fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix);
  56.     ++y_outline;
  57.     fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix);
  58.     ++y_outline;
  59.     fprintf(code_file, "#define yylen %slen\n", symbol_prefix);
  60.     ++y_outline;
  61.     fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix);
  62.     ++y_outline;
  63.     fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix);
  64.     ++y_outline;
  65.     fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix);
  66.     ++y_outline;
  67.     fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix);
  68.     ++y_outline;
  69.     fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix);
  70.     ++y_outline;
  71.     fprintf(code_file, "#define yytable %stable\n", symbol_prefix);
  72.     ++y_outline;
  73.     fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix);
  74.     ++y_outline;
  75.     fprintf(code_file, "#define yyname %sname\n", symbol_prefix);
  76.     ++y_outline;
  77.     fprintf(code_file, "#define yyrule %srule\n", symbol_prefix);
  78.     }
  79.     ++y_outline;
  80.     fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix);
  81. }
  82.  
  83.  
  84. static void output_rule_data(void)
  85. {
  86.     register int i;
  87.     register int j;
  88.  
  89.   
  90.     fprintf(output_file, "short %slhs[] = {%42d,", symbol_prefix,
  91.         symbol_value[start_symbol]);
  92.  
  93.     j = 10;
  94.     for (i = 3; i < nrules; i++)
  95.     {
  96.     if (j >= 10)
  97.     {
  98.         if (!rflag) ++y_outline;
  99.         putc('\n', output_file);
  100.         j = 1;
  101.     }
  102.         else
  103.         ++j;
  104.  
  105.         fprintf(output_file, "%5d,", symbol_value[rlhs[i]]);
  106.     }
  107.     if (!rflag) y_outline += 2;
  108.     fprintf(output_file, "\n};\n");
  109.  
  110.     fprintf(output_file, "short %slen[] = {%42d,", symbol_prefix, 2);
  111.  
  112.     j = 10;
  113.     for (i = 3; i < nrules; i++)
  114.     {
  115.     if (j >= 10)
  116.     {
  117.         if (!rflag) ++y_outline;
  118.         putc('\n', output_file);
  119.         j = 1;
  120.     }
  121.     else
  122.       j++;
  123.  
  124.         fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1);
  125.     }
  126.     if (!rflag) y_outline += 2;
  127.     fprintf(output_file, "\n};\n");
  128. }
  129.  
  130.  
  131. static void output_yydefred(void)
  132. {
  133.     register int i, j;
  134.  
  135.     fprintf(output_file, "short %sdefred[] = {%39d,", symbol_prefix,
  136.         (defred[0] ? defred[0] - 2 : 0));
  137.  
  138.     j = 10;
  139.     for (i = 1; i < nstates; i++)
  140.     {
  141.     if (j < 10)
  142.         ++j;
  143.     else
  144.     {
  145.         if (!rflag) ++y_outline;
  146.         putc('\n', output_file);
  147.         j = 1;
  148.     }
  149.  
  150.     fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0));
  151.     }
  152.  
  153.     if (!rflag) y_outline += 2;
  154.     fprintf(output_file, "\n};\n");
  155. }
  156.  
  157.  
  158.  
  159. static void token_actions(void)
  160. {
  161.     register int i, j;
  162.     register int shiftcount, reducecount;
  163.     register int max, min;
  164.     register short *actionrow, *r, *s;
  165.     register action *p;
  166.  
  167.     actionrow = NEW2(2*ntokens, short);
  168.     for (i = 0; i < nstates; ++i)
  169.     {
  170.     if (parser[i])
  171.     {
  172.         for (j = 0; j < 2*ntokens; ++j)
  173.         actionrow[j] = 0;
  174.  
  175.         shiftcount = 0;
  176.         reducecount = 0;
  177.         for (p = parser[i]; p; p = p->next)
  178.         {
  179.         if (p->suppressed == 0)
  180.         {
  181.             if (p->action_code == SHIFT)
  182.             {
  183.             ++shiftcount;
  184.             actionrow[p->symbol] = p->number;
  185.             }
  186.             else if (p->action_code == REDUCE && p->number != defred[i])
  187.             {
  188.             ++reducecount;
  189.             actionrow[p->symbol + ntokens] = p->number;
  190.             }
  191.         }
  192.         }
  193.  
  194.         tally[i] = shiftcount;
  195.         tally[nstates+i] = reducecount;
  196.         width[i] = 0;
  197.         width[nstates+i] = 0;
  198.         if (shiftcount > 0)
  199.         {
  200.         froms[i] = r = NEW2(shiftcount, short);
  201.         tos[i] = s = NEW2(shiftcount, short);
  202.         min = MAXSHORT;
  203.         max = 0;
  204.         for (j = 0; j < ntokens; ++j)
  205.         {
  206.             if (actionrow[j])
  207.             {
  208.             if (min > symbol_value[j])
  209.                 min = symbol_value[j];
  210.             if (max < symbol_value[j])
  211.                 max = symbol_value[j];
  212.             *r++ = symbol_value[j];
  213.             *s++ = actionrow[j];
  214.             }
  215.         }
  216.         width[i] = max - min + 1;
  217.         }
  218.         if (reducecount > 0)
  219.         {
  220.         froms[nstates+i] = r = NEW2(reducecount, short);
  221.         tos[nstates+i] = s = NEW2(reducecount, short);
  222.         min = MAXSHORT;
  223.         max = 0;
  224.         for (j = 0; j < ntokens; ++j)
  225.         {
  226.             if (actionrow[ntokens+j])
  227.             {
  228.             if (min > symbol_value[j])
  229.                 min = symbol_value[j];
  230.             if (max < symbol_value[j])
  231.                 max = symbol_value[j];
  232.             *r++ = symbol_value[j];
  233.             *s++ = actionrow[ntokens+j] - 2;
  234.             }
  235.         }
  236.         width[nstates+i] = max - min + 1;
  237.         }
  238.     }
  239.     }
  240.     FREE(actionrow);
  241. }
  242.  
  243. static int default_goto(int symbol)
  244. {
  245.     register int i;
  246.     register int m;
  247.     register int n;
  248.     register int default_state;
  249.     register int max;
  250.  
  251.     m = goto_map[symbol];
  252.     n = goto_map[symbol + 1];
  253.  
  254.     if (m == n) return (0);
  255.  
  256.     for (i = 0; i < nstates; i++)
  257.     state_count[i] = 0;
  258.  
  259.     for (i = m; i < n; i++)
  260.     state_count[to_state[i]]++;
  261.  
  262.     max = 0;
  263.     default_state = 0;
  264.     for (i = 0; i < nstates; i++)
  265.     {
  266.     if (state_count[i] > max)
  267.     {
  268.         max = state_count[i];
  269.         default_state = i;
  270.     }
  271.     }
  272.  
  273.     return (default_state);
  274. }
  275.  
  276.  
  277.  
  278.  
  279.  
  280. static void save_column(int symbol, int default_state)
  281. {
  282.     register int i;
  283.     register int m;
  284.     register int n;
  285.     register short *sp;
  286.     register short *sp1;
  287.     register short *sp2;
  288.     register int count;
  289.     register int symno;
  290.  
  291.     m = goto_map[symbol];
  292.     n = goto_map[symbol + 1];
  293.  
  294.     count = 0;
  295.     for (i = m; i < n; i++)
  296.     {
  297.     if (to_state[i] != default_state)
  298.         ++count;
  299.     }
  300.     if (count == 0) return;
  301.  
  302.     symno = symbol_value[symbol] + 2*nstates;
  303.  
  304.     froms[symno] = sp1 = sp = NEW2(count, short);
  305.     tos[symno] = sp2 = NEW2(count, short);
  306.  
  307.     for (i = m; i < n; i++)
  308.     {
  309.     if (to_state[i] != default_state)
  310.     {
  311.         *sp1++ = from_state[i];
  312.         *sp2++ = to_state[i];
  313.     }
  314.     }
  315.  
  316.     tally[symno] = count;
  317.     width[symno] = sp1[-1] - sp[0] + 1;
  318. }
  319.  
  320. static void goto_actions(void)
  321. {
  322.     register int i, j, k;
  323.  
  324.     state_count = NEW2(nstates, short);
  325.  
  326.     k = default_goto(start_symbol + 1);
  327.     fprintf(output_file, "short %sdgoto[] = {%40d,", symbol_prefix, k);
  328.     save_column(start_symbol + 1, k);
  329.  
  330.     j = 10;
  331.     for (i = start_symbol + 2; i < nsyms; i++)
  332.     {
  333.     if (j >= 10)
  334.     {
  335.         if (!rflag) ++y_outline;
  336.         putc('\n', output_file);
  337.         j = 1;
  338.     }
  339.     else
  340.         ++j;
  341.  
  342.     k = default_goto(i);
  343.     fprintf(output_file, "%5d,", k);
  344.     save_column(i, k);
  345.     }
  346.  
  347.     if (!rflag) y_outline += 2;
  348.     fprintf(output_file, "\n};\n");
  349.     FREE(state_count);
  350. }
  351.  
  352. static void sort_actions(void)
  353. {
  354.   register int i;
  355.   register int j;
  356.   register int k;
  357.   register int t;
  358.   register int w;
  359.  
  360.   order = NEW2(nvectors, short);
  361.   nentries = 0;
  362.  
  363.   for (i = 0; i < nvectors; i++)
  364.     {
  365.       if (tally[i] > 0)
  366.     {
  367.       t = tally[i];
  368.       w = width[i];
  369.       j = nentries - 1;
  370.  
  371.       while (j >= 0 && (width[order[j]] < w))
  372.         j--;
  373.  
  374.       while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
  375.         j--;
  376.  
  377.       for (k = nentries - 1; k > j; k--)
  378.         order[k + 1] = order[k];
  379.  
  380.       order[j + 1] = i;
  381.       nentries++;
  382.     }
  383.     }
  384. }
  385.  
  386.  
  387.  
  388.  
  389. /*  The function matching_vector determines if the vector specified by    */
  390. /*  the input parameter matches a previously considered    vector.  The    */
  391. /*  test at the start of the function checks if the vector represents    */
  392. /*  a row of shifts over terminal symbols or a row of reductions, or a    */
  393. /*  column of shifts over a nonterminal symbol.  Berkeley Yacc does not    */
  394. /*  check if a column of shifts over a nonterminal symbols matches a    */
  395. /*  previously considered vector.  Because of the nature of LR parsing    */
  396. /*  tables, no two columns can match.  Therefore, the only possible    */
  397. /*  match would be between a row and a column.  Such matches are    */
  398. /*  unlikely.  Therefore, to save time, no attempt is made to see if a    */
  399. /*  column matches a previously considered vector.            */
  400. /*                                    */
  401. /*  Matching_vector is poorly designed.  The test could easily be made    */
  402. /*  faster.  Also, it depends on the vectors being in a specific    */
  403. /*  order.                                */
  404.  
  405. static int matching_vector(int vector)
  406. {
  407.     register int i;
  408.     register int j;
  409.     register int k;
  410.     register int t;
  411.     register int w;
  412.     register int match;
  413.     register int prev;
  414.  
  415.     i = order[vector];
  416.     if (i >= 2*nstates)
  417.     return (-1);
  418.  
  419.     t = tally[i];
  420.     w = width[i];
  421.  
  422.     for (prev = vector - 1; prev >= 0; prev--)
  423.     {
  424.     j = order[prev];
  425.     if (width[j] != w || tally[j] != t)
  426.         return (-1);
  427.  
  428.     match = 1;
  429.     for (k = 0; match && k < t; k++)
  430.     {
  431.         if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
  432.         match = 0;
  433.     }
  434.  
  435.     if (match)
  436.         return (j);
  437.     }
  438.  
  439.     return (-1);
  440. }
  441.  
  442.  
  443.  
  444. static int pack_vector(int vector)
  445. {
  446.     register int i, j, k, l;
  447.     register int t;
  448.     register int loc;
  449.     register int ok;
  450.     register short *from;
  451.     register short *to;
  452.     int newmax;
  453.  
  454.     i = order[vector];
  455.     t = tally[i];
  456.     assert(t);
  457.  
  458.     from = froms[i];
  459.     to = tos[i];
  460.  
  461.     j = lowzero - from[0];
  462.     for (k = 1; k < t; ++k)
  463.     if (lowzero - from[k] > j)
  464.         j = lowzero - from[k];
  465.     for (;; ++j)
  466.     {
  467.     if (j == 0)
  468.         continue;
  469.     ok = 1;
  470.     for (k = 0; ok && k < t; k++)
  471.     {
  472.         loc = j + from[k];
  473.         if (loc >= maxtable)
  474.         {
  475.         if (loc >= MAXTABLE)
  476.             fatal("maximum table size exceeded");
  477.  
  478.         newmax = maxtable;
  479.         do { newmax += 200; } while (newmax <= loc);
  480.         table = (short *) REALLOC(table, newmax*sizeof(short));
  481.         if (table == 0) no_space();
  482.         check = (short *) REALLOC(check, newmax*sizeof(short));
  483.         if (check == 0) no_space();
  484.         for (l  = maxtable; l < newmax; ++l)
  485.         {
  486.             table[l] = 0;
  487.             check[l] = -1;
  488.         }
  489.         maxtable = newmax;
  490.         }
  491.  
  492.         if (check[loc] != -1)
  493.         ok = 0;
  494.     }
  495.     for (k = 0; ok && k < vector; k++)
  496.     {
  497.         if (pos[k] == j)
  498.         ok = 0;
  499.     }
  500.     if (ok)
  501.     {
  502.         for (k = 0; k < t; k++)
  503.         {
  504.         loc = j + from[k];
  505.         table[loc] = to[k];
  506.         check[loc] = from[k];
  507.         if (loc > high) high = loc;
  508.         }
  509.  
  510.         while (check[lowzero] != -1)
  511.         ++lowzero;
  512.  
  513.         return (j);
  514.     }
  515.     }
  516. }
  517.  
  518. static void pack_table(void)
  519. {
  520.     register int i;
  521.     register int place;
  522.     register int state;
  523.  
  524.     base = NEW2(nvectors, short);
  525.     pos = NEW2(nentries, short);
  526.  
  527.     maxtable = 1000;
  528.     table = NEW2(maxtable, short);
  529.     check = NEW2(maxtable, short);
  530.  
  531.     lowzero = 0;
  532.     high = 0;
  533.  
  534.     for (i = 0; i < maxtable; i++)
  535.     check[i] = -1;
  536.  
  537.     for (i = 0; i < nentries; i++)
  538.     {
  539.     state = matching_vector(i);
  540.  
  541.     if (state < 0)
  542.         place = pack_vector(i);
  543.     else
  544.         place = base[state];
  545.  
  546.     pos[i] = place;
  547.     base[order[i]] = place;
  548.     }
  549.  
  550.     for (i = 0; i < nvectors; i++)
  551.     {
  552.     if (froms[i])
  553.         FREE(froms[i]);
  554.     if (tos[i])
  555.         FREE(tos[i]);
  556.     }
  557.  
  558.     FREE(froms);
  559.     FREE(tos);
  560.     FREE(pos);
  561. }
  562.  
  563.  
  564. static void output_base(void)
  565. {
  566.     register int i, j;
  567.  
  568.     fprintf(output_file, "short %ssindex[] = {%39d,", symbol_prefix, base[0]);
  569.  
  570.     j = 10;
  571.     for (i = 1; i < nstates; i++)
  572.     {
  573.     if (j >= 10)
  574.     {
  575.         if (!rflag) ++y_outline;
  576.         putc('\n', output_file);
  577.         j = 1;
  578.     }
  579.     else
  580.         ++j;
  581.  
  582.     fprintf(output_file, "%5d,", base[i]);
  583.     }
  584.  
  585.     if (!rflag) y_outline += 2;
  586.     fprintf(output_file, "\n};\nshort %srindex[] = {%39d,", symbol_prefix,
  587.         base[nstates]);
  588.  
  589.     j = 10;
  590.     for (i = nstates + 1; i < 2*nstates; i++)
  591.     {
  592.     if (j >= 10)
  593.     {
  594.         if (!rflag) ++y_outline;
  595.         putc('\n', output_file);
  596.         j = 1;
  597.     }
  598.     else
  599.         ++j;
  600.  
  601.     fprintf(output_file, "%5d,", base[i]);
  602.     }
  603.  
  604.     if (!rflag) y_outline += 2;
  605.     fprintf(output_file, "\n};\nshort %sgindex[] = {%39d,", symbol_prefix,
  606.         base[2*nstates]);
  607.  
  608.     j = 10;
  609.     for (i = 2*nstates + 1; i < nvectors - 1; i++)
  610.     {
  611.     if (j >= 10)
  612.     {
  613.         if (!rflag) ++y_outline;
  614.         putc('\n', output_file);
  615.         j = 1;
  616.     }
  617.     else
  618.         ++j;
  619.  
  620.     fprintf(output_file, "%5d,", base[i]);
  621.     }
  622.  
  623.     if (!rflag) y_outline += 2;
  624.     fprintf(output_file, "\n};\n");
  625.     FREE(base);
  626. }
  627.  
  628.  
  629.  
  630. static void output_table(void)
  631. {
  632.     register int i;
  633.     register int j;
  634.  
  635.     ++y_outline;
  636.     fprintf(code_file, "#define YYTABLESIZE %d\n", high);
  637.     fprintf(output_file, "short %stable[] = {%40d,", symbol_prefix,
  638.         table[0]);
  639.  
  640.     j = 10;
  641.     for (i = 1; i <= high; i++)
  642.     {
  643.     if (j >= 10)
  644.     {
  645.         if (!rflag) ++y_outline;
  646.         putc('\n', output_file);
  647.         j = 1;
  648.     }
  649.     else
  650.         ++j;
  651.  
  652.     fprintf(output_file, "%5d,", table[i]);
  653.     }
  654.  
  655.     if (!rflag) y_outline += 2;
  656.     fprintf(output_file, "\n};\n");
  657.     FREE(table);
  658. }
  659.  
  660.  
  661.  
  662. static void output_check(void)
  663. {
  664.     register int i;
  665.     register int j;
  666.  
  667.     fprintf(output_file, "short %scheck[] = {%40d,", symbol_prefix,
  668.         check[0]);
  669.  
  670.     j = 10;
  671.     for (i = 1; i <= high; i++)
  672.     {
  673.     if (j >= 10)
  674.     {
  675.         if (!rflag) ++y_outline;
  676.         putc('\n', output_file);
  677.         j = 1;
  678.     }
  679.     else
  680.         ++j;
  681.  
  682.     fprintf(output_file, "%5d,", check[i]);
  683.     }
  684.  
  685.     if (!rflag) y_outline += 2;
  686.     fprintf(output_file, "\n};\n");
  687.     FREE(check);
  688. }
  689.  
  690.  
  691. static int is_C_identifier(char *name)
  692. {
  693.     register char *s;
  694.     register int c;
  695.  
  696.     s = name;
  697.     c = *s;
  698.     if (c == '"')
  699.     {
  700.     c = *++s;
  701.     if (!isalpha(c) && c != '_' && c != '$')
  702.         return (0);
  703.     while ((c = *++s) != '"')
  704.     {
  705.         if (!isalnum(c) && c != '_' && c != '$')
  706.         return (0);
  707.     }
  708.     return (1);
  709.     }
  710.  
  711.     if (!isalpha(c) && c != '_' && c != '$')
  712.     return (0);
  713.     while ((c = *++s)!=0)
  714.     {
  715.     if (!isalnum(c) && c != '_' && c != '$')
  716.         return (0);
  717.     }
  718.     return (1);
  719. }
  720.  
  721.  
  722. static void output_defines(void)
  723. {
  724.     register int c, i;
  725.     register char *s;
  726.  
  727.     for (i = 2; i < ntokens; ++i)
  728.     {
  729.     s = symbol_name[i];
  730.     if (is_C_identifier(s))
  731.     {
  732.         fprintf(code_file, "#define ");
  733.         if (dflag) fprintf(defines_file, "#define ");
  734.         c = *s;
  735.         if (c == '"')
  736.         {
  737.         while ((c = *++s) != '"')
  738.         {
  739.             putc(c, code_file);
  740.             if (dflag) putc(c, defines_file);
  741.         }
  742.         }
  743.         else
  744.         {
  745.         do
  746.         {
  747.             putc(c, code_file);
  748.             if (dflag) putc(c, defines_file);
  749.         }
  750.         while ((c = *++s)!=0);
  751.         }
  752.         ++y_outline;
  753.         fprintf(code_file, " %d\n", symbol_value[i]);
  754.         if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]);
  755.     }
  756.     }
  757.  
  758.     ++y_outline;
  759.     fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]);
  760.  
  761.     if (dflag && unionized)
  762.     {
  763.     fclose(union_file);
  764.     union_file = fopen(union_file_name, "r");
  765.     if (union_file == NULL) open_error(union_file_name);
  766.     while ((c = getc(union_file)) != EOF)
  767.         putc(c, defines_file);
  768.     fprintf(defines_file, " YYSTYPE;\nextern YYSTYPE %slval;\n",
  769.         symbol_prefix);
  770.     }
  771. }
  772.  
  773.  
  774. static void output_stored_text(void)
  775. {
  776.     register int c;
  777.     register FILE *in, *out;
  778.  
  779.     fclose(text_file);
  780.     text_file = fopen(text_file_name, "r");
  781.     if (text_file == NULL)
  782.     open_error(text_file_name);
  783.     in = text_file;
  784.     if ((c = getc(in)) == EOF)
  785.     return;
  786.     out = code_file;
  787.     if (c ==  '\n')
  788.     ++y_outline;
  789.     putc(c, out);
  790.     while ((c = getc(in)) != EOF)
  791.     {
  792.     if (c == '\n')
  793.         ++y_outline;
  794.     putc(c, out);
  795.     }
  796.     if (!lflag)
  797.     fprintf(out, line_format, ++y_outline + 1, code_file_name);
  798. }
  799.  
  800.  
  801. static void output_debug(void)
  802. {
  803.     register int i, j, k, max;
  804.     char **symnam, *s;
  805.  
  806.     ++y_outline;
  807.     fprintf(code_file, "#define YYFINAL %d\n", final_state);
  808.     y_outline += 3;
  809.     fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
  810.         tflag);
  811.     if (rflag)
  812.     fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n",
  813.         tflag);
  814.  
  815.     max = 0;
  816.     for (i = 2; i < ntokens; ++i)
  817.     if (symbol_value[i] > max)
  818.         max = symbol_value[i];
  819.     ++y_outline;
  820.     fprintf(code_file, "#define YYMAXTOKEN %d\n", max);
  821.  
  822.     symnam = (char **) MALLOC((max+1)*sizeof(char *));
  823.     if (symnam == 0) no_space();
  824.  
  825.     /* Note that it is  not necessary to initialize the element        */
  826.     /* symnam[max].                            */
  827.     for (i = 0; i < max; ++i)
  828.     symnam[i] = 0;
  829.     for (i = ntokens - 1; i >= 2; --i)
  830.     symnam[symbol_value[i]] = symbol_name[i];
  831.     symnam[0] = "end-of-file";
  832.  
  833.     if (!rflag) ++y_outline;
  834.     fprintf(output_file, "#if YYDEBUG\nchar *%sname[] = {", symbol_prefix);
  835.     j = 80;
  836.     for (i = 0; i <= max; ++i)
  837.     {
  838.     if ((s = symnam[i])!=0)
  839.     {
  840.         if (s[0] == '"')
  841.         {
  842.         k = 7;
  843.         while (*++s != '"')
  844.         {
  845.             ++k;
  846.             if (*s == '\\')
  847.             {
  848.             k += 2;
  849.             if (*++s == '\\')
  850.                 ++k;
  851.             }
  852.         }
  853.         j += k;
  854.         if (j > 80)
  855.         {
  856.             if (!rflag) ++y_outline;
  857.             putc('\n', output_file);
  858.             j = k;
  859.         }
  860.         fprintf(output_file, "\"\\\"");
  861.         s = symnam[i];
  862.         while (*++s != '"')
  863.         {
  864.             if (*s == '\\')
  865.             {
  866.             fprintf(output_file, "\\\\");
  867.             if (*++s == '\\')
  868.                 fprintf(output_file, "\\\\");
  869.             else
  870.                 putc(*s, output_file);
  871.             }
  872.             else
  873.             putc(*s, output_file);
  874.         }
  875.         fprintf(output_file, "\\\"\",");
  876.         }
  877.         else if (s[0] == '\'')
  878.         {
  879.         if (s[1] == '"')
  880.         {
  881.             j += 7;
  882.             if (j > 80)
  883.             {
  884.             if (!rflag) ++y_outline;
  885.             putc('\n', output_file);
  886.             j = 7;
  887.             }
  888.             fprintf(output_file, "\"'\\\"'\",");
  889.         }
  890.         else
  891.         {
  892.             k = 5;
  893.             while (*++s != '\'')
  894.             {
  895.             ++k;
  896.             if (*s == '\\')
  897.             {
  898.                 k += 2;
  899.                 if (*++s == '\\')
  900.                 ++k;
  901.             }
  902.             }
  903.             j += k;
  904.             if (j > 80)
  905.             {
  906.             if (!rflag) ++y_outline;
  907.             putc('\n', output_file);
  908.             j = k;
  909.             }
  910.             fprintf(output_file, "\"'");
  911.             s = symnam[i];
  912.             while (*++s != '\'')
  913.             {
  914.             if (*s == '\\')
  915.             {
  916.                 fprintf(output_file, "\\\\");
  917.                 if (*++s == '\\')
  918.                 fprintf(output_file, "\\\\");
  919.                 else
  920.                 putc(*s, output_file);
  921.             }
  922.             else
  923.                 putc(*s, output_file);
  924.             }
  925.             fprintf(output_file, "'\",");
  926.         }
  927.         }
  928.         else
  929.         {
  930.         k = strlen(s) + 3;
  931.         j += k;
  932.         if (j > 80)
  933.         {
  934.             if (!rflag) ++y_outline;
  935.             putc('\n', output_file);
  936.             j = k;
  937.         }
  938.         putc('"', output_file);
  939.         do { putc(*s, output_file); } while (*++s);
  940.         fprintf(output_file, "\",");
  941.         }
  942.     }
  943.     else
  944.     {
  945.         j += 2;
  946.         if (j > 80)
  947.         {
  948.         if (!rflag) ++y_outline;
  949.         putc('\n', output_file);
  950.         j = 2;
  951.         }
  952.         fprintf(output_file, "0,");
  953.     }
  954.     }
  955.     if (!rflag) y_outline += 2;
  956.     fprintf(output_file, "\n};\n");
  957.     FREE(symnam);
  958.  
  959.     if (!rflag) ++y_outline;
  960.     fprintf(output_file, "char *%srule[] = {\n", symbol_prefix);
  961.     for (i = 2; i < nrules; ++i)
  962.     {
  963.     fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]);
  964.     for (j = rrhs[i]; ritem[j] > 0; ++j)
  965.     {
  966.         s = symbol_name[ritem[j]];
  967.         if (s[0] == '"')
  968.         {
  969.         fprintf(output_file, " \\\"");
  970.         while (*++s != '"')
  971.         {
  972.             if (*s == '\\')
  973.             {
  974.             if (s[1] == '\\')
  975.                 fprintf(output_file, "\\\\\\\\");
  976.             else
  977.                 fprintf(output_file, "\\\\%c", s[1]);
  978.             ++s;
  979.             }
  980.             else
  981.             putc(*s, output_file);
  982.         }
  983.         fprintf(output_file, "\\\"");
  984.         }
  985.         else if (s[0] == '\'')
  986.         {
  987.         if (s[1] == '"')
  988.             fprintf(output_file, " '\\\"'");
  989.         else if (s[1] == '\\')
  990.         {
  991.             if (s[2] == '\\')
  992.             fprintf(output_file, " '\\\\\\\\");
  993.             else
  994.             fprintf(output_file, " '\\\\%c", s[2]);
  995.             s += 2;
  996.             while (*++s != '\'')
  997.             putc(*s, output_file);
  998.             putc('\'', output_file);
  999.         }
  1000.         else
  1001.             fprintf(output_file, " '%c'", s[1]);
  1002.         }
  1003.         else
  1004.         fprintf(output_file, " %s", s);
  1005.     }
  1006.     if (!rflag) ++y_outline;
  1007.     fprintf(output_file, "\",\n");
  1008.     }
  1009.  
  1010.     if (!rflag) y_outline += 2;
  1011.     fprintf(output_file, "};\n#endif\n");
  1012. }
  1013.  
  1014.  
  1015. static void output_stype(void)
  1016. {
  1017.     if (!unionized && ntags == 0)
  1018.     {
  1019.     y_outline += 3;
  1020.     fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n");
  1021.     }
  1022. }
  1023.  
  1024.  
  1025. static void output_trailing_text(void)
  1026. {
  1027.     register int c, last;
  1028.     register FILE *in, *out;
  1029.  
  1030.     if (line == 0)
  1031.     return;
  1032.  
  1033.     in = input_file;
  1034.     out = code_file;
  1035.     c = *cptr;
  1036.     if (c == '\n')
  1037.     {
  1038.     ++lineno;
  1039.     if ((c = getc(in)) == EOF)
  1040.         return;
  1041.     if (!lflag)
  1042.     {
  1043.         ++y_outline;
  1044.         fprintf(out, line_format, lineno, input_file_name);
  1045.     }
  1046.     if (c == '\n')
  1047.         ++y_outline;
  1048.     putc(c, out);
  1049.     last = c;
  1050.     }
  1051.     else
  1052.     {
  1053.     if (!lflag)
  1054.     {
  1055.         ++y_outline;
  1056.         fprintf(out, line_format, lineno, input_file_name);
  1057.     }
  1058.     do { putc(c, out); } while ((c = *++cptr) != '\n');
  1059.     ++y_outline;
  1060.     putc('\n', out);
  1061.     last = '\n';
  1062.     }
  1063.  
  1064.     while ((c = getc(in)) != EOF)
  1065.     {
  1066.     if (c == '\n')
  1067.         ++y_outline;
  1068.     putc(c, out);
  1069.     last = c;
  1070.     }
  1071.  
  1072.     if (last != '\n')
  1073.     {
  1074.     ++y_outline;
  1075.     putc('\n', out);
  1076.     }
  1077.     if (!lflag)
  1078.     fprintf(out, line_format, ++y_outline + 1, code_file_name);
  1079. }
  1080.  
  1081.  
  1082. static void output_semantic_actions(void)
  1083. {
  1084.     register int c, last;
  1085.     register FILE *out;
  1086.  
  1087.     fclose(action_file);
  1088.     action_file = fopen(action_file_name, "r");
  1089.     if (action_file == NULL)
  1090.     open_error(action_file_name);
  1091.  
  1092.     if ((c = getc(action_file)) == EOF)
  1093.     return;
  1094.  
  1095.     out = code_file;
  1096.     last = c;
  1097.     if (c == '\n')
  1098.     ++y_outline;
  1099.     putc(c, out);
  1100.     while ((c = getc(action_file)) != EOF)
  1101.     {
  1102.     if (c == '\n')
  1103.         ++y_outline;
  1104.     putc(c, out);
  1105.     last = c;
  1106.     }
  1107.  
  1108.     if (last != '\n')
  1109.     {
  1110.     ++y_outline;
  1111.     putc('\n', out);
  1112.     }
  1113.  
  1114.     if (!lflag)
  1115.     fprintf(out, line_format, ++y_outline + 1, code_file_name);
  1116. }
  1117.  
  1118.  
  1119. static void free_itemsets(void)
  1120. {
  1121.     register core *cp, *next;
  1122.  
  1123.     FREE(state_table);
  1124.     for (cp = first_state; cp; cp = next)
  1125.     {
  1126.     next = cp->next;
  1127.     FREE(cp);
  1128.     }
  1129. }
  1130.  
  1131.  
  1132. static void free_shifts(void)
  1133. {
  1134.     register shifts *sp, *next;
  1135.  
  1136.     FREE(shift_table);
  1137.     for (sp = first_shift; sp; sp = next)
  1138.     {
  1139.     next = sp->next;
  1140.     FREE(sp);
  1141.     }
  1142. }
  1143.  
  1144.  
  1145.  
  1146. static void free_reductions(void)
  1147. {
  1148.     register reductions *rp, *next;
  1149.  
  1150.     FREE(reduction_table);
  1151.     for (rp = first_reduction; rp; rp = next)
  1152.     {
  1153.     next = rp->next;
  1154.     FREE(rp);
  1155.     }
  1156. }
  1157.  
  1158. static void output_actions(void)
  1159. {
  1160.     nvectors = 2*nstates + nvars;
  1161.  
  1162.     froms = NEW2(nvectors, short *);
  1163.     tos = NEW2(nvectors, short *);
  1164.     tally = NEW2(nvectors, short);
  1165.     width = NEW2(nvectors, short);
  1166.  
  1167.     token_actions();
  1168.     FREE(lookaheads);
  1169.     FREE(LA);
  1170.     FREE(LAruleno);
  1171.     FREE(accessing_symbol);
  1172.  
  1173.     goto_actions();
  1174.     FREE(goto_map + ntokens);
  1175.     FREE(from_state);
  1176.     FREE(to_state);
  1177.  
  1178.     sort_actions();
  1179.     pack_table();
  1180.     output_base();
  1181.     output_table();
  1182.     output_check();
  1183. }
  1184.  
  1185. void output(void)
  1186. {
  1187.     free_itemsets();
  1188.     free_shifts();
  1189.     free_reductions();
  1190.     output_prefix();
  1191.     output_stored_text();
  1192.     output_defines();
  1193.     output_rule_data();
  1194.     output_yydefred();
  1195.     output_actions();
  1196.     free_parser();
  1197.     output_debug();
  1198.     output_stype();
  1199.     if (rflag) write_section(tables);
  1200.     write_section(header);
  1201.     output_trailing_text();
  1202.     write_section(body);
  1203.     output_semantic_actions();
  1204.     write_section(trailer);
  1205. }
  1206.